package pri.jz.keeper.repository

import android.os.Handler
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.asLiveData
import androidx.lifecycle.switchMap
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import pri.jz.keeper.db.UserDao
import pri.jz.keeper.entity.User
import pri.jz.keeper.exception.JException
import pri.jz.keeper.webservice.entityT.UserT
import pri.jz.keeper.webservice.retrofit.UserService

/**
 *Author by: JZ
 *Email: 2451756617@qq.com
 *PS:
 */
class UserRepository(
    private val userService: UserService,
    private val userDao: UserDao,
) {
    private val TAG = "UserRepository"

    private val _userId = MutableLiveData(-1)
    var userId: Int
        get() = _userId.value ?: -1
        set(value) {
            if (value != _userId.value) _userId.postValue(value)
        }

    private val _user = _userId.switchMap {
        findFromDB(it)
    }
    val user: LiveData<User?>
        get() = _user


    /**
     * 从数据库查询用户信息
     * @param id
     * @return
     */
    fun findFromDB(id: Int): LiveData<User?> {
        return userDao.findById(id)
    }

    /**
     * 从服务器获取用户信息
     * @param number
     * @return
     */
    suspend fun findFromService(number: String): UserT {
        return userService.getUser(number)
    }

    suspend fun saveUser() = withContext(Dispatchers.IO) {
        user.value?.let { user ->
            userService.modifyUser(user.toUserT())
            userDao.update(user)
        }
    }

    /**
     * 刷新用户信息
     * @param number
     * @return
     */
    suspend fun loadUser(id: Int){
        val userResponse = userService.userLoading(id)
        Log.d(TAG, "loadUser: $userResponse")
        userDao.insert(userResponse.toUser())
        userId = id
    }

    /**
     * 将用户存储到服务器于数据库中
     * @param user
     * @param addFailed
     */
    suspend fun insertToService(
        user: User,
    ) {
        userService.addUser(user.toUserT())
    }

    suspend fun insertToDb(
        user: User
    ) {
        userDao.insert(user)
    }


    companion object {
        @Volatile private var instance: UserRepository? = null
        fun getIns(userDao: UserDao,userService: UserService): UserRepository =
            instance ?: synchronized(this) {
                UserRepository(userService, userDao).also { instance = it }
            }
        fun getIns(): UserRepository {
            if (instance == null)
                throw JException.InsNullJException
            return instance!!
        }
    }

}